Imports System.IO

Public Class Map
    Private imgMap As Bitmap
    Private tiles(,) As String
    Private intFrame As Integer
    Private intFrameLimit As Integer = 2
    Private numColumns As Integer
    Private numRows As Integer
    Public left As Integer = 0

    Private images As New Collection()
    Private Const MAP_FOLDER As String = "../../Content/Maps/"
    Private Const IMG_FOLDER As String = "../../Content/Images/"
    Dim lastimage As String = "B1"

    Public Sub New()
        LoadMap(MAP_FOLDER & "lvl1.map")
        CreateBitmap()
        LoadImages()
    End Sub

    Private Sub LoadImages()
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block1.png"), "B1")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block2.png"), "B2")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block3.png"), "B3")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block4.png"), "B4")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block5.png"), "B5")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block6.png"), "B6")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block7.png"), "B7")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block8.png"), "B8")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block2.png"), "B14")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block3.png"), "B13")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block4.png"), "B12")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block5.png"), "B11")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block6.png"), "B10")
        images.Add(New Bitmap(IMG_FOLDER & "Block ani/block7.png"), "B9")
    End Sub
    Public Sub Draw(ByRef e As System.Windows.Forms.PaintEventArgs)
        'THE X POSITION WILL HAVE TO CHANGE DEPENDING ON WHAT PART OF THE MAP SHOULD BE VISIBLE
        'FOR NOW WE'LL LEAVE IT AT ZERO
        e.Graphics.DrawImage(imgMap, New Point(left, 0))
        'animate()
    End Sub

    Public Function getColumn(ByVal objSprite As Sprite) As Integer
        Dim xPos As Integer = objSprite.location.X + 4 - left
        Dim yPos As Integer = objSprite.location.Y + 4
        Return Math.Floor(Math.Abs(xPos) / 32)
    End Function

    Private Function getCurrentGroundLeft(ByVal objSprite As Sprite) As Integer
        Dim xPos As Integer = objSprite.location.X + 4 - left
        Dim yPos As Integer = objSprite.location.Y + 4
        getCurrentGroundLeft = 0
        Dim x As Integer = Math.Floor(Math.Abs(xPos) / 32)
        If x >= numColumns Then x = numColumns
        If x < 0 Then x = 0
        For y As Integer = 0 To numRows
            If Not tiles(x, y).Contains("0") Then
                If yPos < (y * 32) Then
                    getCurrentGroundLeft = y * 32
                    If getCurrentGroundLeft > yPos Then
                        y = numRows
                    End If
                End If
            End If
        Next
    End Function

    Private Function getCurrentGroundRight(ByVal objSprite As Sprite) As Integer
        Dim xPos As Integer = objSprite.location.X + objSprite.Bitmap.Width - 4 - left
        Dim yPos As Integer = objSprite.location.Y + objSprite.Bitmap.Height - 4
        getCurrentGroundRight = 0
        Dim x As Integer = Math.Floor(Math.Abs(xPos) / 32)
        If x >= numColumns Then x = numColumns
        If x < 0 Then x = 0
        For y As Integer = 0 To numRows
            If Not tiles(x, y).Contains("0") Then
                If yPos < (y * 32) Then
                    getCurrentGroundRight = y * 32
                    If getCurrentGroundRight > yPos Then
                        y = numRows
                    End If
                End If
            End If
        Next
    End Function

    Public Function getCurrentGround(ByVal objSprite As Sprite) As Integer
        getCurrentGround = 0
        Dim leftGround As Integer = 0
        Dim rightGround As Integer = 0

        ''get ground on the Left side
        'Dim xLeft As Integer = Math.Floor(Math.Abs(objSprite.location.X) / 32)
        'If xLeft >= numColumns Then xLeft = numColumns
        'If xLeft < 0 Then xLeft = 0
        'For y As Integer = 0 To numRows
        '    If Not tiles(xLeft, y).Contains("0") Then
        '        leftGround = y * 32
        '        If leftGround > objSprite.location.Y + objSprite.Bitmap.Height Then
        '            y = numRows
        '        End If
        '    End If
        'Next

        ''Now for the right side
        'Dim xRight As Integer = Math.Floor(Math.Abs(objSprite.location.X + objSprite.Bitmap.Width) / 32)
        'If xRight >= numColumns Then xRight = numColumns
        'If xRight < 0 Then xRight = 0
        'For y As Integer = 0 To numRows
        '    If Not tiles(xRight, y).Contains("0") Then
        '        rightGround = y * 32
        '        If rightGround > objSprite.location.Y + objSprite.Bitmap.Height Then
        '            y = numRows
        '        End If
        '    End If
        'Next

        rightGround = getCurrentGroundRight(objSprite)
        leftGround = getCurrentGroundLeft(objSprite)
        If rightGround < leftGround Then
            getCurrentGround = rightGround
        Else
            getCurrentGround = leftGround
        End If

    End Function

    ''' <summary>
    ''' Detects collision to the right of a sprite with the map
    ''' </summary>
    ''' <param name="objSprite">Sprite to check</param>
    ''' <param name="xDistance">Distance to right the sprite wants to move</param>
    ''' <returns>"0" if the sprite can move right, otherwise returns the left position of the object in the way</returns>
    ''' <remarks></remarks>
    Public Function canMoveRight(ByVal objSprite As Sprite, ByVal xDistance As Integer) As Integer
        canMoveRight = 0
        Dim center As Point
        center = objSprite.location + New Point(objSprite.Bitmap.Width * 0.5, objSprite.Bitmap.Height * 0.5)
        Dim spriteX As Integer = objSprite.location.X - left
        Dim x As Integer = Math.Floor(Math.Abs(spriteX + objSprite.Bitmap.Width + xDistance) / 32)
        Dim y As Integer = Math.Floor(Math.Abs(center.Y) / 32)

        If x <= numColumns And x >= 0 Then
            If Not tiles(x, y).Contains("0") Then
                canMoveRight = (x * 32) + left
            End If
        End If
    End Function

    ''' <summary>
    ''' Detects collision to the right of a sprite with the map
    ''' </summary>
    ''' <param name="objSprite">Sprite to check</param>
    ''' <param name="xDistance">Distance to right the sprite wants to move</param>
    ''' <returns>"0" if the sprite can move right, otherwise returns the Right position of the object in the way</returns>
    ''' <remarks></remarks>
    Public Function canMoveLeft(ByVal objSprite As Sprite, ByVal xDistance As Integer) As Integer
        canMoveLeft = 0
        Dim center As Point
        center = objSprite.location + New Point(objSprite.Bitmap.Width * 0.5, objSprite.Bitmap.Height * 0.5)
        Dim spriteX As Integer = objSprite.location.X - left
        Dim x As Integer = Math.Floor(Math.Abs(spriteX - xDistance) / 32)
        Dim y As Integer = Math.Floor(Math.Abs(center.Y) / 32)

        If x <= numColumns And x >= 0 Then
            If Not tiles(x, y).Contains("0") Then
                canMoveLeft = ((x * 32) + 32) + left
            End If
        End If
    End Function

    Private Sub CreateBitmap()
        Dim tempGround As New Bitmap(IMG_FOLDER & "Grass.png")
        Dim tempBlock As New Bitmap(IMG_FOLDER & "Block.png")
        Dim tempQ As New Bitmap(IMG_FOLDER & "Block ani/block1.png")

        imgMap = New Bitmap(32 * (numColumns + 1), 32 * (numRows + 1))
        Dim g As Graphics = Graphics.FromImage(imgMap)

        For x As Integer = 0 To numColumns
            For y As Integer = 0 To numRows
                If tiles(x, y) = "1" Then
                    g.DrawImageUnscaled(tempGround, (32 * x), (32 * y))
                ElseIf tiles(x, y) = "2" Then
                    g.DrawImageUnscaled(tempBlock, (32 * x), (32 * y))
                ElseIf tiles(x, y) = "3" Then
                    g.DrawImageUnscaled(tempQ, (32 * x), (32 * y))
                End If
            Next
        Next
    End Sub

    Private Sub LoadMap(ByVal mapPath As String)
        Dim reader As New StreamReader(mapPath)

        Dim str() As String
        str = reader.ReadLine().Split(",")

        numColumns = str(0) - 1
        numRows = str(1) - 1
        ReDim tiles(numColumns, numRows)

        For y As Integer = 0 To numRows
            Dim strLine() As String
            strLine = reader.ReadLine().Split(",")

            For x As Integer = 0 To numColumns
                tiles(x, y) = strLine(x).Trim
            Next
        Next
    End Sub

    Private Sub animate()
        intFrame += 1
        Dim g As Graphics = Graphics.FromImage(imgMap)
        If intFrame > intFrameLimit Then
            For y As Integer = 0 To numRows
                For x As Integer = 0 To numColumns
                    If tiles(x, y) = "3" Then
                        Select Case lastimage
                            Case "B1"
                                g.DrawImageUnscaled(images("B2"), (32 * x), (32 * y))
                                lastimage = "B2"
                            Case "B2"
                                g.DrawImageUnscaled(images("B3"), (32 * x), (32 * y))
                                lastimage = "B3"
                            Case "B3"
                                g.DrawImageUnscaled(images("B4"), (32 * x), (32 * y))
                                lastimage = "B4"
                            Case "B4"
                                g.DrawImageUnscaled(images("B5"), (32 * x), (32 * y))
                                lastimage = "B5"
                            Case "B5"
                                g.DrawImageUnscaled(images("B6"), (32 * x), (32 * y))
                                lastimage = "B6"
                            Case "B6"
                                g.DrawImageUnscaled(images("B7"), (32 * x), (32 * y))
                                lastimage = "B7"
                            Case "B7"
                                g.DrawImageUnscaled(images("B8"), (32 * x), (32 * y))
                                lastimage = "B8"
                            Case "B8"
                                g.DrawImageUnscaled(images("B9"), (32 * x), (32 * y))
                                lastimage = "B9"
                            Case "B9"
                                g.DrawImageUnscaled(images("B10"), (32 * x), (32 * y))
                                lastimage = "B10"
                            Case "B10"
                                g.DrawImageUnscaled(images("B11"), (32 * x), (32 * y))
                                lastimage = "B11"
                            Case "B11"
                                g.DrawImageUnscaled(images("B12"), (32 * x), (32 * y))
                                lastimage = "B12"
                            Case "B12"
                                g.DrawImageUnscaled(images("B13"), (32 * x), (32 * y))
                                lastimage = "B13"
                            Case "B13"
                                g.DrawImageUnscaled(images("B14"), (32 * x), (32 * y))
                                lastimage = "B14"
                            Case "B14"
                                g.DrawImageUnscaled(images("B1"), (32 * x), (32 * y))
                                lastimage = "B1"
                        End Select
                    End If
                Next
            Next
            intFrame = 0
        End If
    End Sub

End Class
